package orm

import (
	"fmt"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/config"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/gin/log"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"time"
)

type Writer struct {
}

func (w Writer) Printf(format string, args ...interface{}) {
	fmt.Printf(format, args...)
}

var mysqlDB *gorm.DB
var d *dbRepo

func init() {
	if config.C.Mysql.Address != "" {
		mysqlDB = ConnectMySql(config.C.Mysql.UserName, config.C.Mysql.Password, config.C.Mysql.Address, config.C.Mysql.Port, config.C.Mysql.DbName)
	}
}

func ConnectMySql(MySqlUserName, Password, Address string, Port int, dbName string) *gorm.DB {
	log.Info(dbName + " mysql  链接中。。。")
	var err error
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		MySqlUserName, Password, Address, Port, dbName)
	newdb, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 使用单数表名，启用该选项，此时，`User` 的表名应该是 `user`
		},
		PrepareStmt: false,
		Logger:      log.NewGorm().LogMode(logger.Info),
	})

	sqlDB, err := newdb.DB()
	if err != nil {
		panic("failed to get db instance")
	}

	// 设置连接池参数
	sqlDB.SetMaxIdleConns(30)                   // 设置最大空闲连接数
	sqlDB.SetMaxOpenConns(300)                  // 设置最大打开连接数
	sqlDB.SetConnMaxLifetime(time.Second * 550) // 设置连接最大生命周期

	if err != nil {
		log.Fatalf("failed to connect database：%v", err)
	}
	log.Info(dbName + " mysql 链接成功")
	return newdb
}

// get db
func GetMysqlDB() *gorm.DB {
	return mysqlDB
}

var _ Repo = (*dbRepo)(nil)

type Repo interface {
	i()
	GetDbR() *gorm.DB
	GetDbW() *gorm.DB
	GetSeafileDb() *gorm.DB
	DbRClose() error
	DbWClose() error
}

type dbRepo struct {
	DbR       *gorm.DB
	DbW       *gorm.DB
	SeafileDb *gorm.DB
}

func GetDBRepo() *dbRepo {
	return d
}

func (d *dbRepo) i() {}

func (d *dbRepo) GetDbR() *gorm.DB {
	return d.DbR
}
func (d *dbRepo) GetDbW() *gorm.DB {
	return d.DbW
}
func (d *dbRepo) GetSeafileDb() *gorm.DB {
	return d.SeafileDb
}

func (d *dbRepo) DbRClose() error {
	sqlDB, _ := d.DbR.DB()
	return sqlDB.Close()
}

func (d *dbRepo) DbWClose() error {
	sqlDB, _ := d.DbW.DB()
	return sqlDB.Close()
}

var mysqlDbMaps = make(map[string]*gorm.DB)

func SetMysqlDb(key string, db *gorm.DB) {
	if db != nil {
		mysqlDbMaps[key] = db
	}
}

func GetMysqlDb() map[string]*gorm.DB {
	return mysqlDbMaps
}

// get db mdb_data_dev
func GetMdbDataDevDb() *gorm.DB {
	return mysqlDbMaps["mdb_data_dev"]
}

// get db view_data_dev
func GetViewDataDevDb() *gorm.DB {
	return mysqlDbMaps["view_data_dev"]
}
